package com.shengsiyuan.netty.firstexample;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;

/**
 * 功能描述：第一个例子 HelloWorld，客户端和服务端进行通讯。
 *
 * 启动后访问地址：http://127.0.0.1:8899/
 */
public class TestServer {

    public static void main(String[] args) throws InterruptedException {
        /**
         * 事件循环组
         *
         * 服务器端编程，像Tomcat，一定会存在一个死循环，不断的接受请求。下面两个就是两个死循环
         *
         * bossGroup：不断地从客户端接收连接，但是不对连接进行处理。接收到连接之后会传给workerGroup，由workerGroup完成真正的对连接的处理。
         * workerGroup：完成真正的对连接的处理。
         *
         * 一个线程组也可以完成功能，但不是一个好的方式，netty推荐使用两个线程组。
         */
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        try {
            // netty提供的非常方便的启动服务端的一个类
            ServerBootstrap serverBootstrap = new ServerBootstrap();

            serverBootstrap
                    // parent (acceptor) and the child (client)
                    .group(bossGroup, workerGroup)
                    // 底层通过反射创建NioServerSocketChannel
                    .channel(NioServerSocketChannel.class)
                    // 服务端的初始化器（可以添加自己编写的处理器（请求到来之后对请求进行处理的））
                    .childHandler(new TestServerInitializer());

            // 绑定端口（监听端口），然后进行同步
            // sync（阻塞方法）用来等待和同步连接
            ChannelFuture channelFuture = serverBootstrap.bind(8899).sync();// 真正的启动
            channelFuture.channel().closeFuture().sync();
        } finally {
            // 优雅关闭
            // 如果关闭的时候有连接还没处理，在可控的时间里，把连接处理完，并不接受新的连接
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }




















}
